package com.csjbot.weedle_auto.serialport_util

import kotlin.experimental.and

/**
 * Copyright (c) 2016, SuZhou CsjBot. All Rights Reserved. <br></br>
 * www.csjbot.com
 *
 * @auther: 陈奇
 * @email: 18362937369@163.com
 * @date 2017/5/27
 */
object DigitalTrans {

    /**
     * 数字字符串转ASCII码字符串
     *
     * @param
     *
     * @return ASCII字符串
     */
    fun StringToAsciiString(content: String): String {
        var result = ""
        val max = content.length
        for (i in 0..max - 1) {
            val c = content[i]
            val b = Integer.toHexString(c.toInt())
            result = result + b
        }
        return result
    }

    /**
     * 十六进制转字符串
     *
     * @param hexString
     * 十六进制字符串
     * @param encodeType
     * 编码类型4：Unicode，2：普通编码
     * @return 字符串
     */
    fun hexStringToString(hexString: String, encodeType: Int): String {
        var result = ""
        val max = hexString.length / encodeType
        for (i in 0..max - 1) {
            val c = DigitalTrans.hexStringToAlgorism(hexString
                    .substring(i * encodeType, (i + 1) * encodeType)).toChar()
            result += c
        }
        return result
    }

    /**
     * 十六进制字符串装十进制
     *
     * @param hex
     * 十六进制字符串
     * @return 十进制数值
     */
    fun hexStringToAlgorism(hex: String): Int {
        val hex1 = hex.toUpperCase()
        val max = hex1.length
        var result = 0
        for (i in max downTo 1) {
            val c = hex[i - 1]
            var algorism: Int
            algorism = if (c in '0'..'9') {
                c - '0'
            } else {
                c.toInt() - 55
            }
            result += (Math.pow(16.0, (max - i).toDouble()) * algorism).toInt()
        }
        return result
    }

    /**
     * 十六转二进制
     *
     * @param hex
     * 十六进制字符串
     * @return 二进制字符串
     */
    fun hexStringToBinary(hex: String): String {
        var result = hex.toUpperCase()
        val max = hex.length
        (0 until max)
                .asSequence()
                .map { hex[it] }
                .forEach {
                    when (it) {
                        '0' -> result += "0000"
                        '1' -> result += "0001"
                        '2' -> result += "0010"
                        '3' -> result += "0011"
                        '4' -> result += "0100"
                        '5' -> result += "0101"
                        '6' -> result += "0110"
                        '7' -> result += "0111"
                        '8' -> result += "1000"
                        '9' -> result += "1001"
                        'A' -> result += "1010"
                        'B' -> result += "1011"
                        'C' -> result += "1100"
                        'D' -> result += "1101"
                        'E' -> result += "1110"
                        'F' -> result += "1111"
                    }
                }
        return result
    }

    /**
     * ASCII码字符串转数字字符串
     *
     * @param
     * ASCII字符串
     * @return 字符串
     */
    fun AsciiStringToString(content: String): String {
        var result = ""
        val length = content.length / 2
        (0 until length)
                .map { content.substring(it * 2, it * 2 + 2) }
                .map { hexStringToAlgorism(it) }
                .map { it.toChar() }
                .map { it.toString() }
                .forEach { result += it }
        return result
    }

    /**
     * 将十进制转换为指定长度的十六进制字符串
     *
     * @param algorism
     * int 十进制数字
     * @param maxLength
     * int 转换后的十六进制字符串长度
     * @return String 转换后的十六进制字符串
     */
    fun algorithmToHEXString(algorism: Int, maxLength: Int): String {
        var result: String
        result = Integer.toHexString(algorism)

        if (result.length % 2 == 1) {
            result = "0" + result
        }
        return patchHexString(result.toUpperCase(), maxLength)
    }

    /**
     * 字节数组转为普通字符串（ASCII对应的字符）
     *
     * @param bytearray
     * byte[]
     * @return String
     */
    fun bytetoString(bytearray: ByteArray): String {
        var result = ""
        var temp: Char

        val length = bytearray.size
        for (i in 0..length - 1) {
            temp = bytearray[i].toChar()
            result += temp
        }
        return result
    }

    /**
     * 二进制字符串转十进制
     *
     * @param binary
     * 二进制字符串
     * @return 十进制数值
     */
    fun binaryToAlgorism(binary: String): Int {
        val max = binary.length
        var result = 0
        for (i in max downTo 1) {
            val c = binary[i - 1]
            val algorism = c - '0'
            result += (Math.pow(2.0, (max - i).toDouble()) * algorism).toInt()
        }
        return result
    }

    /**
     * 十进制转换为十六进制字符串
     *
     * @param algorithm
     * int 十进制的数字
     * @return String 对应的十六进制字符串
     */
    fun algorithmToHEXString(algorithm: Int): String {
        var result: String
        result = Integer.toHexString(algorithm)

        if (result.length % 2 == 1) {
            result = "0" + result

        }
        return result.toUpperCase()
    }

    /**
     * HEX字符串前补0，主要用于长度位数不足。
     *
     * @param str
     * String 需要补充长度的十六进制字符串
     * @param maxLength
     * int 补充后十六进制字符串的长度
     * @return 补充结果
     */
    fun patchHexString(str: String, maxLength: Int): String {
        var msg: String
        var temp = ""
        for (i in 0 until maxLength - str.length) {
            temp = "0" + temp
        }
        msg = (temp + str).substring(0, maxLength)
        return msg
    }

    /**
     * 将一个字符串转换为int
     *
     * @param s
     * String 要转换的字符串
     * @param defaultInt
     * int 如果出现异常,默认返回的数字
     * @param radix
     * int 要转换的字符串是什么进制的,如16 8 10.
     * @return int 转换后的数字
     */
    fun parseToInt(s: String, defaultInt: Int, radix: Int): Int {
        var i: Int =
                try {
                    Integer.parseInt(s, radix)
                } catch (ex: NumberFormatException) {
                    defaultInt
                }
        return i
    }

    /**
     * 将一个十进制形式的数字字符串转换为int
     *
     * @param s
     * String 要转换的字符串
     * @param defaultInt
     * int 如果出现异常,默认返回的数字
     * @return int 转换后的数字
     */
    fun parseToInt(s: String, defaultInt: Int): Int {
        var i: Int =
                try {
                    Integer.parseInt(s)
                } catch (ex: NumberFormatException) {
                    defaultInt
                }
        return i
    }

    /**
     * 十六进制字符串转为Byte数组,每两个十六进制字符转为一个Byte
     *
     * @param hex
     * 十六进制字符串
     * @return byte 转换结果
     */
    fun hexStringToByte(hex: String): ByteArray {
        val max = hex.length / 2
        val bytes = ByteArray(max)
        val binaries = DigitalTrans.hexStringToBinary(hex)
        for (i in 0 until max) {
            bytes[i] = DigitalTrans.binaryToAlgorism(binaries.substring(
                    i * 8 + 1, (i + 1) * 8)).toByte()
            if (binaries[8 * i] == '1') {
                bytes[i] = (0 - bytes[i]).toByte()
            }
        }
        return bytes
    }

    /**
     * 十六进制串转化为byte数组
     *
     * @return the array of byte
     */
    @Throws(IllegalArgumentException::class)
    fun hex2byte(hex: String): ByteArray {
        if (hex.length % 2 != 0) {
            throw IllegalArgumentException()
        }
        val arr = hex.toCharArray()
        val b = ByteArray(hex.length / 2)
        var i = 0
        var j = 0
        val l = hex.length
        while (i < l) {
            val swap = "" + arr[i++] + arr[i]
            val byteint = Integer.parseInt(swap, 16) and 0xFF
            b[j] = byteint.toByte()
            i++
            j++
        }
        return b
    }

    /**
     * 字节数组转换为十六进制字符串
     *
     * @param b
     * byte[] 需要转换的字节数组
     * @return String 十六进制字符串
     */
    fun byte2hex(b: ByteArray?): String {
        if (b == null) {
            throw IllegalArgumentException(
                    "Argument b ( byte array ) is null! ")
        }
        var hs = ""
        b.indices
                .asSequence()
                .map { Integer.toHexString((b[it] and 0xff.toByte()).toInt()) }
                .forEach {
                    hs =
                            if (it.length == 1) {
                                hs + "0" + it
                            } else {
                                hs + it
                            }
                }
        return hs.toUpperCase()
    }
}
